
//
// 101113 - AH - Created.
// 101123 - AH - Renamed from SoekratData which I needed for the interface that
//               this now implements.
// 110112 - AH - (Fantoft) Made set methods return this.
// 110308 - AH - Name property.
// 110325 - AH - SpareWheelNetwork introduced.
// 110423 - AH - Pit introduced.
// 110530 - AH - getTitle() and setTitle().
// 110716 - AH - (Bien *) setMotorConfigurstion(Motor) and 
//               getMotorConfigurstion().
// 120128 - AH - (Garage) getProductTable().
//

package org.soekrat.engine.io;

import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import org.soekrat.engine.forest.Forest;
import org.soekrat.engine.mine.Mine;
import org.soekrat.engine.motor.passingstrategies.SequenceWheelProcessing;
import org.soekrat.engine.network.Network;
import org.soekrat.engine.ontology.OntologyDatastructure;
import org.soekrat.engine.ontology.ptable.ProductTable;
import org.soekrat.engine.pit.Pit;
import org.soekrat.engine.swnetwork.SpareWheelNetwork;

/**
 * <p>
 *   Soekrat data.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC) 
 */
public final class DefaultSoekratData implements SoekratData
{
  private String m_title=null;
  
  private String m_name="sokrat";
  
  private SequenceWheelProcessing m_swp=null;
  //private MotorConfiguration m_mc=null;
  
  private final Map<String, OntologyDatastructure> m_ods=
    new HashMap<String, OntologyDatastructure>();
  
  //private Mine m_mine=null;
  
  //private Network m_network=null;
  
  //private Forest m_forest=null;
  
  private SpareWheelNetwork m_snetwork=null;
  
  private Pit m_pit=null;
  
  /**
   * <p>
   *   Creates empty data set.
   * </p>
   */
  public DefaultSoekratData(){}
  
  /**
   * <p>
   *   Creates empty data set.
   * </p>
   * @param name {@link #getName()}.
   */
  public DefaultSoekratData(String name)
  {
    if (name==null)
    {
      throw new NullPointerException("name");
    }
    
    m_name=name;
  }
  
  /**
   * <p>
   *   Sets
   *   {@link MotorConfiguration}.
   * </p>
   * @param motor {@code MotorConfiguration} or {@code null} if to clear.
   * @return {@code this}.
   */
  /*
  public DefaultSoekratData setMotorConfiguration(MotorConfiguration mc)
  { 
    m_mc=mc; 
    return this; 
  }
  */
  public DefaultSoekratData setSequenceWheelProcessing(
    SequenceWheelProcessing swp)
  {
    m_swp=swp;
    return this;
  }
  
  /**
   * <p>
   *   Adds
   *   {@link OntologyDatastructure}.
   * </p>
   * @param od {@link OntologyDatastructure} to add.
   * @return {@code this}.
   */
  public DefaultSoekratData addOntologyDatastructure(OntologyDatastructure od)
  {
    if (od==null)
    {
      throw new NullPointerException("od");
    }
    
    m_ods.put(od.getClass().getName(), od);
    return this;
  }
  
  // Specified in SoekratData. 
  public OntologyDatastructure getOntologyDatastructure(String name)
  {
    if (name==null)
    {
      throw new NullPointerException("name");
    }
    
    return m_ods.get(name);
  }

  /**
   * <p>
   *   Sets
   *   {@link Mine}.
   * </p>
   * @param mine {@code Mine} or {@code null} if to clear.
   * @return {@code this}.
   */
  //public DefaultSoekratData setMine(Mine mine){ m_mine=mine; return this; }
  
  /**
   * <p>
   *   Sets
   *   {@link Mine}.
   * </p>
   * @param mine {@code Mine} or {@code null} if to clear.
   * @return {@code this}.
   */
  /*
  public DefaultSoekratData setForest(Forest forest)
  { 
    m_forest=forest; 
    return this; 
  }
  */
  
  /**
   * <p>
   *   Sets
   *   {@link Network}.
   * </p>
   * @param network {@code Network} ot {@code null} if to clear.
   * @param {@code this}.
   */
  /*
  public DefaultSoekratData setNetwork(Network network)
  { 
    m_network=network;
    return this;
  }
  */
  
  /**
   * <p>
   *   Sets
   *   {@link SpareWheelNetwork}.
   * </p>
   * @param network {@code SpareWheelNetwork} or {@code null} if to clear.
   * @param {@code this}.
   */
  public DefaultSoekratData setSpareWheelNetwork(SpareWheelNetwork network)
  { 
    m_snetwork=network;
    return this;
  }
  
  /**
   * <p>
   *   Sets
   *   {@link Pit}.
   * </p>
   * @param pit {@code Pit} or {@code null} if to clear.
   * @param {@code this}.
   */
  public DefaultSoekratData setPit(Pit pit){ m_pit=pit; return this; }
  
  /**
   * <p>
   *   Sets title that should be used for data set.
   * </p>
   * @param title Title, if {@code null} or the empty 
   *              {@code String}
   *              {@link #getTitle()} will return 
   *              {@link #getName()} else returns {@code title}.
   */
  public void setTitle(String title)
  {
    title=(title==null) ? "" : title.trim();
    m_title=(title.length()==0) ? null : title; 
  }
  
  // Specified in SoekratData.
  public String getTitle()
  {
    return m_title=(m_title==null) ? getName() : m_title;
  }

  // Specified in SoekratData.
  public String getName(){ return m_name; }

  // Specified in SoekratData.
  //public MotorConfiguration getMotorConfiguration(){ return m_mc; }
  
  // Specified in SoekratData.
  public Mine getMine(){ return (Mine)m_ods.get(Mine.class.getName()); }
  
  // Specified in SoekratData.
  public Forest getForest(){ return (Forest)m_ods.get(Forest.class.getName()); }
  
  // Specified in SoekratData.
  public Network getNetwork()
  { 
    return (Network)m_ods.get(Network.class.getName()); 
  }
  
  // Specified in SoekratData.
  public ProductTable getProductTable()
  {
    return (ProductTable)m_ods.get(ProductTable.class.getName());
  }
  
  // Specified in SoekratData.
  public SpareWheelNetwork getSpareWheelNetwork(){ return m_snetwork; }
  
  // Specified in SoekratData.
  public SequenceWheelProcessing getSequenceWheelProcessing(){ return m_swp; }
  
  // Specified in SoekratData.  
  public Pit getPit(){ return m_pit; }
  
  @Override
  public String toString() 
  {
    CharArrayWriter caw=new CharArrayWriter();
    PrintWriter pw=new PrintWriter(caw);
    
    for (Map.Entry<String, OntologyDatastructure> curr : m_ods.entrySet())
    {
      pw.println(curr.getKey());
      pw.println();
      pw.println(curr.getValue());
    }
    
    pw.flush();
    return caw.toString();
  }
  
}
